import SwiftUI

struct ScenarioListView: View {
    @EnvironmentObject var recorder: MotionRecorder
    
    @State private var selectedScenario: Scenario?
    @State private var pendingDuration: Double = 60
    @State private var activeScenario: Scenario?
    
    @State private var showCountdown: Bool = false
    @State private var countdownValue: Int = 3
    
    @State private var isRecording: Bool = false
    @State private var recordingProgress: Double = 0
    @State private var recordingStartDate: Date?
    @State private var recordingTotalSec: Double = 60
    @State private var timer: Timer?
    
    @State private var showNoteSheet: Bool = false
    @State private var noteText: String = ""
    @State private var lastSession: Session?
    @State private var sessions: [Session] = []
    
    private let columns = [
        GridItem(.flexible(), spacing: 16),
        GridItem(.flexible(), spacing: 16)
    ]
    
    var body: some View {
        NavigationStack {
            ZStack {
                // 背景渐变
                LinearGradient(colors: [.black.opacity(0.95), .blue.opacity(0.5)], startPoint: .topLeading, endPoint: .bottomTrailing)
                    .ignoresSafeArea()
                
                ScrollView {
                    VStack(alignment: .leading, spacing: 16) {
                        header
                        LazyVGrid(columns: columns, spacing: 16) {
                            ForEach(Scenario.all) { scenario in
                                ScenarioCard(scenario: scenario)
                                    .onTapGesture {
                                        selectedScenario = scenario
                                        pendingDuration = scenario.defaultDurationSec
                                    }
                            }
                        }
                        .padding(.top, 8)
                    }
                    .padding(20)
                }
            }
            .navigationTitle("采集场景")
            .toolbarTitleDisplayMode(.inline)
            .sheet(item: $selectedScenario) { scenario in
                ScenarioConfirmSheet(
                    scenario: scenario,
                    duration: $pendingDuration,
                    onCancel: { selectedScenario = nil },
                    onConfirm: { startCountdown(for: scenario, seconds: pendingDuration) }
                )
                .presentationDetents([.height(360), .medium])
                .presentationCornerRadius(20)
            }
            .overlay(countdownOverlay)
            .overlay(recordingHUD)
            .sheet(isPresented: $showNoteSheet) {
                NoteInputSheet(noteText: $noteText) { note in
                    if var session = lastSession {
                        session.note = note
                        sessions.append(session)
                    }
                    noteText = ""
                    lastSession = nil
                    activeScenario = nil
                }
                .presentationDetents([.height(260), .medium])
                .presentationCornerRadius(20)
            }
        }
        .preferredColorScheme(.dark)
    }
    
    private var header: some View {
        VStack(alignment: .leading, spacing: 6) {
            HStack(spacing: 10) {
                Image(systemName: "record.circle.fill")
                    .foregroundStyle(.red, .white)
                    .font(.system(size: 22))
                Text("选择一个场景开始采集")
                    .font(.system(.title3, design: .rounded).weight(.semibold))
            }
            Text("支持 AirPods 头部运动数据。开始前请确保耳机已连接并佩戴。")
                .font(.footnote)
                .foregroundColor(.white.opacity(0.7))
        }
    }
    
    // MARK: - Countdown
    private var countdownOverlay: some View {
        Group {
            if showCountdown {
                ZStack {
                    Color.black.opacity(0.6).ignoresSafeArea()
                    VStack(spacing: 20) {
                        Text("准备开始")
                            .font(.system(.title2, design: .rounded).weight(.medium))
                            .foregroundColor(.white.opacity(0.9))
                        Text("\(countdownValue)")
                            .font(.system(size: 80, weight: .heavy, design: .rounded))
                            .foregroundStyle(LinearGradient(colors: [.blue, .cyan], startPoint: .topLeading, endPoint: .bottomTrailing))
                            .shadow(color: .blue.opacity(0.5), radius: 10, x: 0, y: 4)
                    }
                }
                .transition(.opacity)
            }
        }
        .animation(.easeInOut, value: showCountdown)
    }
    
    // MARK: - Recording HUD
    private var recordingHUD: some View {
        Group {
            if isRecording {
                ZStack {
                    Color.black.opacity(0.45).ignoresSafeArea()
                    VStack(spacing: 24) {
                        ZStack {
                            Circle()
                                .stroke(lineWidth: 10)
                                .foregroundColor(.white.opacity(0.08))
                                .frame(width: 180, height: 180)
                            Circle()
                                .trim(from: 0, to: recordingProgress)
                                .stroke(AngularGradient(colors: [.red, .orange, .yellow, .green, .cyan, .blue, .purple, .red], center: .center), style: StrokeStyle(lineWidth: 10, lineCap: .round))
                                .rotationEffect(.degrees(-90))
                                .frame(width: 180, height: 180)
                                .animation(.easeInOut(duration: 0.2), value: recordingProgress)
                            VStack(spacing: 6) {
                                Image(systemName: "waveform.path.ecg")
                                    .font(.system(size: 24, weight: .bold))
                                    .foregroundColor(.white)
                                Text(timeRemainingString)
                                    .font(.system(.title3, design: .rounded).weight(.semibold))
                                    .foregroundColor(.white)
                            }
                        }
                        
                        HStack(spacing: 16) {
                            Button(role: .destructive) {
                                finishRecording(earlyStop: true)
                            } label: {
                                Label("提前结束", systemImage: "stop.circle.fill")
                                    .font(.system(.headline, design: .rounded))
                                    .padding(.horizontal, 18).padding(.vertical, 10)
                                    .background(.ultraThinMaterial)
                                    .cornerRadius(12)
                            }
                        }
                    }
                    .padding(24)
                    .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 24, style: .continuous))
                    .shadow(color: .black.opacity(0.35), radius: 30, x: 0, y: 20)
                    .padding(24)
                }
                .transition(.opacity)
            }
        }
        .animation(.easeInOut, value: isRecording)
    }
    
    private var timeRemainingString: String {
        guard let start = recordingStartDate else { return "--:--" }
        let elapsed = Date().timeIntervalSince(start)
        let remaining = max(0, recordingTotalSec - elapsed)
        let m = Int(remaining) / 60
        let s = Int(remaining) % 60
        return String(format: "%02d:%02d", m, s)
    }
    
    // MARK: - Flow
    private func startCountdown(for scenario: Scenario, seconds: Double) {
        selectedScenario = nil
        activeScenario = scenario
        countdownValue = 3
        showCountdown = true
        
        Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { t in
            countdownValue -= 1
            if countdownValue <= 0 {
                t.invalidate()
                showCountdown = false
                beginRecording(scenario: scenario, seconds: seconds)
            }
        }
    }
    
    private func beginRecording(scenario: Scenario, seconds: Double) {
        activeScenario = scenario
        recordingTotalSec = seconds
        recordingStartDate = Date()
        recordingProgress = 0
        isRecording = true
        
        // 清空旧数据并开始
        recorder.dataPoints.removeAll()
        recorder.start()
        
        timer?.invalidate()
        timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { t in
            guard let start = recordingStartDate else { return }
            let elapsed = Date().timeIntervalSince(start)
            recordingProgress = min(1.0, elapsed / recordingTotalSec)
            if elapsed >= recordingTotalSec {
                t.invalidate()
                finishRecording(earlyStop: false, scenario: scenario, actualDuration: elapsed)
            }
        }
    }
    
    private func finishRecording(earlyStop: Bool, scenario: Scenario? = nil, actualDuration: Double? = nil) {
        timer?.invalidate(); timer = nil
        recorder.stop()
        isRecording = false
        
        // 生成会话并请求备注
        let usedScenario = scenario ?? activeScenario ?? selectedScenario
        if let scenario = usedScenario, let start = recordingStartDate {
            let end = Date()
            let duration = actualDuration ?? end.timeIntervalSince(start)
            let session = Session(scenario: scenario, startDate: start, endDate: end, durationSec: duration, note: nil)
            lastSession = session
            showNoteSheet = true
        } else {
            // 若缺少上下文，也给出一个兜底的会话
            let scen = activeScenario ?? selectedScenario ?? Scenario.all.first!
            let now = Date()
            let session = Session(scenario: scen, startDate: now.addingTimeInterval(-1), endDate: now, durationSec: 1, note: nil)
            lastSession = session
            showNoteSheet = true
        }
    }
}

// MARK: - Components
private struct ScenarioCard: View {
    let scenario: Scenario
    
    var body: some View {
        VStack(alignment: .leading, spacing: 10) {
            ZStack(alignment: .topLeading) {
                LinearGradient(colors: scenario.gradient, startPoint: .topLeading, endPoint: .bottomTrailing)
                    .frame(height: 120)
                    .overlay(
                        RoundedRectangle(cornerRadius: 20, style: .continuous)
                            .strokeBorder(.white.opacity(0.12), lineWidth: 1)
                    )
                    .clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous))
                    .shadow(color: scenario.gradient.last?.opacity(0.35) ?? .black.opacity(0.35), radius: 18, x: 0, y: 12)
                
                VStack(alignment: .leading, spacing: 8) {
                    HStack(spacing: 10) {
                        Image(systemName: scenario.icon)
                            .font(.system(size: 22, weight: .semibold))
                            .foregroundColor(.white)
                        Text(scenario.title)
                            .font(.system(.headline, design: .rounded).weight(.bold))
                            .foregroundColor(.white)
                        Spacer()
                    }
                    Text(scenario.subtitle)
                        .font(.footnote)
                        .foregroundColor(.white.opacity(0.9))
                        .lineLimit(2)
                    
                    HStack(spacing: 6) {
                        Image(systemName: "timer")
                            .font(.caption)
                            .foregroundColor(.white.opacity(0.9))
                        Text(durationLabel)
                            .font(.caption)
                            .foregroundColor(.white.opacity(0.9))
                    }
                }
                .padding(14)
            }
        }
        .contentShape(Rectangle())
    }
    
    private var durationLabel: String {
        if scenario.hasRange {
            return "建议时长：\(format(min: scenario.minDurationSec, max: scenario.maxDurationSec))"
        } else {
            return "建议时长：\(format(seconds: scenario.minDurationSec))"
        }
    }
    
    private func format(min: Double, max: Double) -> String {
        let a = format(seconds: min)
        let b = format(seconds: max)
        return "\(a) – \(b)"
    }
    private func format(seconds: Double) -> String {
        if seconds >= 60 {
            return String(format: "%.0f 分钟", seconds/60)
        } else {
            return String(format: "%.0f 秒", seconds)
        }
    }
}

private struct ScenarioConfirmSheet: View {
    let scenario: Scenario
    @Binding var duration: Double
    var onCancel: () -> Void
    var onConfirm: () -> Void
    
    var body: some View {
        VStack(spacing: 16) {
            Capsule().fill(.secondary.opacity(0.4)).frame(width: 40, height: 5).padding(.top, 8)
            HStack(spacing: 12) {
                Image(systemName: scenario.icon)
                    .font(.system(size: 22, weight: .semibold))
                    .foregroundStyle(LinearGradient(colors: scenario.gradient, startPoint: .topLeading, endPoint: .bottomTrailing))
                VStack(alignment: .leading) {
                    Text(scenario.title).font(.headline)
                    Text(scenario.subtitle).font(.subheadline).foregroundColor(.secondary)
                }
                Spacer()
            }
            
            VStack(alignment: .leading, spacing: 8) {
                Text("请根据提示准备：")
                    .font(.subheadline).fontWeight(.semibold)
                Text("• 请确保 AirPods 已连接并佩戴\n• 按提示开始后将倒计时 3,2,1\n• 期间尽量保持符合该场景的动作")
                    .font(.footnote)
                    .foregroundColor(.secondary)
            }
            .frame(maxWidth: .infinity, alignment: .leading)
            .padding()
            .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16))
            
            if scenario.hasRange {
                VStack(alignment: .leading) {
                    HStack {
                        Text("选择时长")
                        Spacer()
                        Text(durationString)
                            .foregroundColor(.secondary)
                    }
                    Slider(value: $duration, in: scenario.minDurationSec...scenario.maxDurationSec, step: 10)
                }
            } else {
                HStack {
                    Text("时长")
                    Spacer()
                    Text(durationString)
                        .foregroundColor(.secondary)
                }
                .onAppear { duration = scenario.minDurationSec }
            }
            
            HStack(spacing: 12) {
                Button("取消", role: .cancel) { onCancel() }
                    .buttonStyle(.bordered)
                Button {
                    onConfirm()
                } label: {
                    Label("开始", systemImage: "play.fill")
                }
                .buttonStyle(.borderedProminent)
            }
            .padding(.top, 4)
            
            Spacer(minLength: 0)
        }
        .padding(20)
    }
    
    private var durationString: String {
        if duration >= 60 { return String(format: "%.0f 分钟", duration/60) }
        return String(format: "%.0f 秒", duration)
    }
}

private struct NoteInputSheet: View {
    @Binding var noteText: String
    var onSave: (String) -> Void
    
    var body: some View {
        VStack(spacing: 16) {
            Capsule().fill(.secondary.opacity(0.4)).frame(width: 40, height: 5).padding(.top, 8)
            Text("记录备注")
                .font(.headline)
            Text("请输入吃的东西（或填：没咀嚼）")
                .font(.footnote)
                .foregroundColor(.secondary)
            TextField("如：花生/苹果/没咀嚼", text: $noteText)
                .textFieldStyle(.roundedBorder)
            HStack(spacing: 12) {
                Button("跳过") { onSave("") }
                    .buttonStyle(.bordered)
                Button("保存") {
                    onSave(noteText)
                }
                .buttonStyle(.borderedProminent)
            }
            Spacer(minLength: 0)
        }
        .padding(20)
    }
}
